/*
 * Copyright 2015 Patrick Ahlbrecht
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.onyxbits.weave;

import java.awt.SplashScreen;
import java.awt.Window;

import javax.swing.JFrame;

/**
 * Defines the lifecycle of the user interface. All methods execute on the UI
 * thread.
 * <p>
 * Instead of implementing this interface, consider extending
 * {@link AbstractLifecycle} instead.
 * 
 * @author patrick
 * 
 */
public interface Lifecycle {

	/**
	 * Called on the beginning of the lifecycle. This method should create and
	 * register global objects.
	 * 
	 * @param globals
	 *          the registry (only contains the {@link LifecycleManager} at this
	 *          point). If the UI is elaborate and/or should not be generated by
	 *          lazy loading, then all windows may already be requested here from
	 *          the {@link LifecycleManager}. This is also a good place to
	 *          finalize the {@link SplashScreen}, if one is used.
	 */
	public void onSetup(Globals globals);

	/**
	 * Called at the end of the lifecycle. This method should take care of any
	 * cleanup that might be required. No user interaction is permitted (or
	 * possible) at this point. NOTE: it is (or it should not be) necessary to
	 * call {@link System#exit(int)} at this point. The {@link LifecycleManager}
	 * will have removed all managed windows which causes the JVM to exit
	 * automatically unless there are background threads (or unmanaged windows).
	 * 
	 * @param globals
	 *          the registry.
	 */
	public void onTeardown(Globals globals);

	/**
	 * Called when the application is suppose to shutdown.
	 * 
	 * @param globals
	 *          the registry
	 * @return true if the application is allowed to shut down, false otherwise.
	 */
	public boolean onRequestShutdown(Globals globals);

	/**
	 * Called when a message gets posted on the system bus via
	 * {@link LifecycleManager#sendBusMessage(Object)}.
	 * 
	 * @param message
	 *          the message object.
	 */
	public void onBusMessage(Globals globals, Object message);

	/**
	 * Called when a secondary window needs to be created. Secondary windows are
	 * typically associated with the "View" menu and manage an aspect of the
	 * application that doesn't fit into the primary window.
	 * 
	 * @param globals
	 *          the registry
	 * @param id
	 *          the unique identifier of the window. By convention this should be
	 *          the classname of whatever class is responsible for assembling the
	 *          content pane.
	 * @return a new instance of the requested window, invisible, but otherwise
	 *         ready to use. NOTE: {@link JFrame}S must use the
	 *         DO_NOTHING_ON_CLOSE policy (the framework automatically sets this).
	 */
	public Window onCreateSecondaryWindow(Globals globals, String id);

	/**
	 * Called when the first window needs to be created. The UI lifecycle will be
	 * bound to it (closing this window will also shut the UI down).
	 * 
	 * @param globals
	 *          the registry
	 * @return a new instance of the primary window, invisible, but otherwise
	 *         ready to use. NOTE: {@link JFrame}S must use the
	 *         DO_NOTHING_ON_CLOSE policy (the framework automatically sets this).
	 */
	public Window onCreatePrimaryWindow(Globals globals);

	/**
	 * Called when a secondary window gets destroyed (either explicitly by
	 * {@link LifecycleManager#destroyWindow(String)} or implicitly
	 * {@link LifecycleManager#shutdown()}. The window object is already disposed
	 * off at this point.
	 * 
	 * @param id
	 *          window identifier
	 */
	public void onDestroySecondaryWindow(String id);

}
